package com.cnoja.jmsncn.kernel;

import java.io.IOException;

import org.apache.log4j.Logger;

import com.cnoja.jmsncn.command.DefaultCommand;
import com.cnoja.jmsncn.command.commands.CVRCommand;
import com.cnoja.jmsncn.command.commands.UserCommand;
import com.cnoja.jmsncn.command.commands.VersionCommand;
import com.cnoja.jmsncn.command.event.CommandEvent;
import com.cnoja.jmsncn.command.event.NotificationHostChangeEvent;
import com.cnoja.jmsncn.inf.ICommand;
import com.cnoja.jmsncn.inf.ICommandEventListener;
import com.cnoja.jmsncn.inf.ICommander;
import com.cnoja.jmsncn.kernel.exceptions.CommandException;
import com.cnoja.jmsncn.kernel.exceptions.CommunicationException;
import com.cnoja.jmsncn.kernel.exceptions.MessengerException;
import com.cnoja.jmsncn.kernel.exceptions.MissingParameterException;
import com.cnoja.jmsncn.utils.command.CommandUtils;
import com.cnoja.jmsncn.utils.system.SystemUtils;
import com.cnoja.jmsncn.utils.text.StringUtils;

public class DefaultMessengerImpl extends AbstractMessenger implements
		ICommandEventListener {

	public DefaultMessengerImpl(String userName, String password) {
		super(userName, password);
	}

	private String host = null;
	private int port = 0;

	private int timeOut = 3;

	private Logger logger = Logger.getLogger(DefaultMessengerImpl.class);
	private ICommander commander = null;

	public long getTimeOut() {
		return timeOut;
	}

	public void setTimeOut(int timeOut) {
		this.timeOut = timeOut;
	}

	public void login() throws MessengerException {

		validateName();
		validatePassword();
		validateHost();
		try {
			commander.start();

			ICommand command = new VersionCommand("VER "+CommandUtils.nextId()+" MSNP8 CVR0");
			command
					.setNext(new CVRCommand(
							"CVR "+CommandUtils.nextId()+" "+SystemUtils.getLocaleId()+" "+SystemUtils.getSystemType()+" "+SystemUtils.getSystemVersion()+" "+SystemUtils.getOSArchitecture()+" MSNMSGR 8.0.0792 msmsgs "+this.getUserName())
							.setNext(new UserCommand(
									"USR "+CommandUtils.nextId()+" TWN I "+getUserName())));

			commander.execute(command);

		} catch (IOException e) {
			throw new CommunicationException(e);
		} catch (CommandException e) {
			e.printStackTrace();
			logger.error(e);
		}

	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public void logout() throws MessengerException {
		// TODO Auto-generated method stub

	}

	public void validateHost() throws MessengerException {
		if (StringUtils.isNullOrEmpty(host)) {
			throw new MissingParameterException(
					"The host name must be provided");
		}
	}

	public void setCommander(ICommander commander) {
		this.commander = commander;
		this.commander.setMessenger(this);
		this.commander.addCommandEventListener(this);

	}

	public void onCommandEvent(CommandEvent event) {
		if (event instanceof NotificationHostChangeEvent) {
			NotificationHostChangeEvent ncEvent = (NotificationHostChangeEvent) event;
			try {
				if (logger.isInfoEnabled()) {
					logger.info("Changing the notification host to :"
							+ ncEvent.getHost() + ":" + ncEvent.getPort());
				}
				this.commander.stop();
				this.commander.start();
				this.setHost(ncEvent.getHost());
				this.setPort(ncEvent.getPort());
				if (logger.isInfoEnabled()) {
					logger.info("Notification host has changed ,now relogin to :"
							+ ncEvent.getHost() + ":" + ncEvent.getPort());
				}
				
				this.login();
			} catch (Exception e) {
				logger.error(e);
			}
		}

	}

}
